﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using ModelPredictPro.Predict.SVM;

namespace ModelPredictPro.WindowForms.UserControls {
    public partial class UCSVMSetting : UserControl, ISVMSetting {
        public UCSVMSetting() {
            InitializeComponent();
        }

        private void UCSVMSetting_Load(object sender, EventArgs e) {
            this.Dock = DockStyle.Top;
            var svmKernelTypes = new EnumBinder<SVM.KernelType>();
            var parallelModes = new EnumBinder<SVM.ParameterSelection.ParallelMode>();
            ddlKernelTypes.DataSource = svmKernelTypes.Pairs;
            ddlParallelMode.DataSource = parallelModes.Pairs;
            ddlKernelTypes.DisplayMember = ddlParallelMode.DisplayMember = "Name";
            ddlKernelTypes.ValueMember = ddlParallelMode.ValueMember = "Enum";
            ddlKernelTypes.SelectedValue = SVM.KernelType.RBF;
            ddlParallelMode.SelectedValue = SVM.ParameterSelection.ParallelMode.None;
        }
        static UCSVMSetting single;
        public static UCSVMSetting SingleInstance {
            get {
                if (single == null) {
                    single = new UCSVMSetting();
                    single.TabIndex = 0;
                    single.Dock = DockStyle.Top;
                }
                return single;
            }
        }
        public SVMFactory CreateSVMFactory() {
            SVMFactory rst = new SVMFactory(this);
            return rst;
        }


        #region ISVMSetting 成员

        public bool UseProbability {
            get {
                return chbUseProbability.Checked;
            }
            set {
                chbUseProbability.Checked = value;
            }
        }


        public double CacheMemorySize {
            get {
                return (double) numCacheMemorySize.Value;
            }
            set {
                numCacheMemorySize.Value = (decimal)value;
            }
        }

        public SVM.KernelType KernelType {
            get {
                return (SVM.KernelType)ddlKernelTypes.SelectedValue;
            }
            set {
                ddlKernelTypes.SelectedValue = value;
            }
        }
        public SVM.ParameterSelection.ParallelMode ParallelModeSetting {
            get { return (SVM.ParameterSelection.ParallelMode)ddlParallelMode.SelectedValue; }
            set { ddlParallelMode.SelectedValue = value; }
        }

        public Dictionary<int, double> Weights {
            get { return GetWeights(); }
            set { SetWeights(value); }
        }

        private Dictionary<int, double> GetWeights() {
            Dictionary<int, double> rst = null;
            string text = txtWeights.Text;
            string[] arr = text.Split(default(char[]), StringSplitOptions.RemoveEmptyEntries);
            if (arr.Length == 0) return rst;
            rst = new Dictionary<int, double>();
            foreach (var item in arr) {
                int index = item.IndexOf(":");
                rst.Add(int.Parse(item.Substring(0, index)), double.Parse(item.Substring(index + 1)));
            }
            return rst;
        }
        private void SetWeights(Dictionary<int, double> value) {
            if (value == null || value.Count == 0)
                txtWeights.Clear();
            StringBuilder sb = new StringBuilder();
            foreach (var item in value) {
                sb.AppendFormat("{0}:{1} ", item.Key, item.Value);
            }
            txtWeights.Text = sb.ToString().Substring(0, sb.Length - 1);
        }

        #endregion

        private void ddlParallelMode_SelectedIndexChanged(object sender, EventArgs e) {
            SVM.ParameterSelection.ParallelMode mode = ((ModelPredictPro.WindowForms.EnumWrapper<SVM.ParameterSelection.ParallelMode>)(ddlParallelMode.SelectedItem)).Enum;
            if (!Program.TASK.HasClients && mode == SVM.ParameterSelection.ParallelMode.MPI) {
                MessageBox.Show("You need to run program from command line to enable MPI-mode, using 'mpiexec -hosts .... [exe]'"+Environment.NewLine +
                    "OR you can choose NormalParallel model to run multi-tasks on one PC.");
                ddlParallelMode.SelectedValue = SVM.ParameterSelection.ParallelMode.NoramlParallel;
            }
        }
    }
}
